package ru.amse.jsynchro.kernel.task;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

import ru.amse.jsynchro.fileSystem.FileSystem;
import ru.amse.jsynchro.kernel.Difference;
import ru.amse.jsynchro.kernel.Operation;
import ru.amse.jsynchro.logging.ILogger;

/**
 * The task implements action of adding 
 * missing files of each folder to each other.
 * Possible conflicts (file with equal names)
 * can be resolved automatically by adding file 
 * from the first folder, or manually by requesting 
 * to the user.
 * 
 * @author miha
 *
 */
public class UndirectedTask extends Task {
    protected List<Difference> firstDiffs;
    protected List<Difference> secondDiffs;
   
    public UndirectedTask(String firstFolder, FileSystem fs1, 
                          String secondFolder, FileSystem fs2, 
                          boolean forceResolveConflicts, ILogger logger) throws IOException {
        super(firstFolder, fs1, secondFolder, fs2, forceResolveConflicts, logger);
    }

    public boolean analyze() {
        secondDiffs = first.compare(second, false);
        firstDiffs = second.compare(first, false);
        List<Difference> atomic = new ArrayList<Difference>();
        first.addAtomicDiffs(secondDiffs, atomic, false);
        secondDiffs.clear();
        secondDiffs.addAll(atomic);
        atomic.clear();
        second.addAtomicDiffs(firstDiffs, atomic, false);
        firstDiffs.clear();
        firstDiffs.addAll(atomic);
        return getDiffsNumber() > 0;
    }
    
    public void synchronize() {
        applyChanges(firstDiffs, second, first);
        applyChanges(secondDiffs, first, second);
    }

    public int getDiffsNumber() {
        return firstDiffs.size() + secondDiffs.size();
    }
    
    protected void resolveConflicts() {
        for (Difference d: secondDiffs) {
            if (d.getOperation() == Operation.CONFLICT) {
                d.setOperation(Operation.NOTHING);
            }
        }
        Scanner sc = new Scanner(System.in);
        for (Difference diff: firstDiffs) {
            if (diff.getOperation() == Operation.CONFLICT) {
                if (forceResolveConflicts) {
                    diff.setOperation(Operation.ADD);
                } else {
                    System.out.println(diff);
                    System.out.println("resolve conflict: update in First, " +
                            "update in Second, Nothing (F, S, N)");
                    String answer = sc.nextLine();
                    answer = answer.toUpperCase();
                    char c = answer.charAt(0);
                    switch (c) {
                    case 'F': diff.setOperation(Operation.ADD);break;
                    case 'S': secondDiffs.add(new Difference(diff.getPath(), Operation.ADD, diff.isDirectory()));
                              diff.setOperation(Operation.NOTHING);
                              break;
                    case 'N': diff.setOperation(Operation.NOTHING);break;
                    //TODO default 
                    default: diff.setOperation(Operation.NOTHING);break;
                    }
                }
            }
        }
        sc.close();
    }
    
    public List<String> getStringDifferences() {
        List<String> result = new ArrayList<String>();
        
        makeStringDifferences(first.getPath(), firstDiffs, result);
        makeStringDifferences(second.getPath(), secondDiffs, result);
        
        return result;
    }

}
